% GalvoScanControl
% Scan script template

% Scan scripts should contain three variables
%  nFs      The sample rate (1/sec between scan points)
%  mXY      A matrix with two columns in the format [X Y], where
%               X  are x-positions
%               Y  are y-positions
%           The unit of this matrix is millimeters, relative to the origin
%  vShut    Vector with same length as mXY where values indicate shutter
%           open/close state (when a shutter is controlled) or the beam
%           intensity (when the output is directed to an intensity
%           modulated laser module, e.g. Coherent CUBE).
%           Note: Values of vShut should not exceed +/- 5V. Values beyond
%           these limits will be fixed at +/- 5V by the software.

% Example 1: Scan entire field in 10 horizontal lines

% Choose template to use
nTemp = 2;

switch nTemp
    case 1
        % Example 1: Scan entire field in 10 horizontal lines

        nRange = 1.5; % max range, mm
        nStep = .5; % step between lines, mm
        nFs = 1 / 0.1; % 1/sec
        nShDur = .01; % sec

        mXY = [];
        nDir = 1; % initial direction
        for y = -nRange:nStep:nRange
            nDir = -nDir; % flip direction
            vX = (-nRange:nStep:nRange).*nDir;
            vY = repmat(y, 1, length(vX));
            mXY = [mXY; vX(:) vY(:)];
        end
        
        vShut = [repmat([0 1]', floor(size(mXY, 1)/2), 1); 0];
        break;
    case 2
        % Example 2: Scan a X-by-Y grid where the beam is exposed for 5 ms
        % at each location. Randomize locations.

        vSize = [2 1]; % grid size X-by-Y, mm
        nVertices = [5 5]; % number of vertices along X and Y directions
        nBeamOnDur = 0.01; % beam exposure duration
        nInterval = 0.1; % interval between vertex traversals
        nFs = 1 / nBeamOnDur; % sample rate, 1/sec -> Hz
        
        % Compute grid locations
        vX = linspace(0, vSize(1), nVertices(1))';
        vY = linspace(0, vSize(2), nVertices(2))';

        % Subtract origin (i.e. subtract 1/2 from each side)
        vX = vX - (vSize(1)/2);
        vY = vY - (vSize(2)/2);
        
        % Assemble all combined vertices
        mXY_pos = [];
        for i = 1:length(vX)
            mXY_pos = [mXY_pos; repmat(vX(i), length(vY), 1) vY];
        end
        
        
        % Randomize order of vertex presentations
        vOrder = randperm(size(mXY_pos, 1));
        mXY_pos = [mXY_pos(vOrder, 1) mXY_pos(vOrder, 2)];

        % Extend matrix so that temporal resolution is nBeamOnDur
        % Before each movement pad mXY with identical prior rows so that
        % the beam moves and stays off at the next position for a duration
        % of nInterval - nBeamOnDur
        nPad = nInterval ./ nBeamOnDur;
        mXY = [];
        vShut = [];
        for i = 1:size(mXY_pos)
            mXY = [mXY; repmat(mXY_pos(i,:), nPad, 1)];
            vShut = [vShut; zeros(nPad-1, 1); 2];
        end
        
        break;
end

figure; plot(mXY(:,1),mXY(:,2), '.-')
